package hu.myai.controller;

import hu.myai.runtimeneural.TrainNeuralNetwork;
import hu.myai.util.SanfordNet;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.joone.log.ILogger;
import org.joone.log.LoggerFactory;
import org.joone.net.NeuralNet;

public class TrainNetwork {

	private static final ILogger log = LoggerFactory.getLogger(TrainNetwork.class);

	public TrainNetwork() {
		super();
	}

	// Type:
	// 1 - a net is trained by all remaining symbol, (skipp the previous in the
	// list)
	// 2 - a net is trained by all symbol
	// 3 - a net trained just the original symbol

	private int trainType = 1;

	public void go(String nnetFile) {
		boolean skipSome = true;

		TrainNetwork thisClass = new TrainNetwork();
		SanfordNet netUtil = new SanfordNet();

		// get the requestes nnet files
		NeuralNet myNet = netUtil.restoreNeuralNet(nnetFile);

		String symbolItem = nnetFile.substring(nnetFile.lastIndexOf(File.separator) + 1, nnetFile.indexOf("_", nnetFile
				.lastIndexOf(File.separator)));

		List<String> symbolList;

		/** training logic */
		if (trainType == 1) {

			// a net is trained by all remaining symbol
			symbolList = netUtil.getAllSymbol();
			skipSome = true;
		} else if (trainType == 2) {

			// a net is trained by all symbol
			symbolList = netUtil.getAllSymbol();
			skipSome = false;
		} else {

			// a net trained just the original symbol
			symbolList = new ArrayList<String>();
			symbolList.add(symbolItem);
			skipSome = false;
		}

		// train each nnet
		while (true) {
			for (String symbol : symbolList) {

				try {
					// skipp all before
					if (!symbol.equals(symbolItem) && skipSome)
						continue;
					else
						skipSome = false;

					log.debug("Train nnet: " + symbol);

					TrainNet sampleNet = thisClass.new TrainNet(myNet);

					sampleNet.go(symbol);

					sampleNet.nnet.join();

					sampleNet.nnet.stop();

					sampleNet.nnet.getMonitor().setExporting(true);
					myNet = sampleNet.nnet.cloneNet();
					sampleNet.nnet.getMonitor().setExporting(false);

					netUtil.saveNeuralNet(sampleNet.nnet, symbol + "_backup.snet");
					log.debug("Saved " + symbol + ": " + sampleNet.nnet.getMonitor().getGlobalError());

				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
			skipSome = false;
		}

	}

	public class TrainNet extends TrainNeuralNetwork {
		public TrainNet(NeuralNet nnet) {
			super(nnet);
		}
	}
}
